#include "common/websocket_frame.h"
#include <algorithm>
#include <stdexcept>

namespace websocket {

WebSocketFrame::WebSocketFrame() 
    : fin_(true), rsv1_(false), rsv2_(false), rsv3_(false),
      opcode_(Opcode::TEXT), masked_(false), payload_length_(0) {
}

WebSocketFrame::WebSocketFrame(Opcode opcode, const std::vector<uint8_t>& payload, bool fin)
    : fin_(fin), rsv1_(false), rsv2_(false), rsv3_(false),
      opcode_(opcode), masked_(false), payload_length_(payload.size()),
      payload_(payload) {
}

std::vector<uint8_t> WebSocketFrame::serialize() const {
    std::vector<uint8_t> frame;
    
    // 第一个字节: FIN + RSV + Opcode
    uint8_t first_byte = (fin_ ? 0x80 : 0x00) | static_cast<uint8_t>(opcode_);
    frame.push_back(first_byte);
    
    // 第二个字节: MASK + Payload length
    uint8_t second_byte = masked_ ? 0x80 : 0x00;
    
    if (payload_length_ <= 125) {
        second_byte |= payload_length_;
        frame.push_back(second_byte);
    } else if (payload_length_ <= 65535) {
        second_byte |= 126;
        frame.push_back(second_byte);
        frame.push_back((payload_length_ >> 8) & 0xFF);
        frame.push_back(payload_length_ & 0xFF);
    } else {
        second_byte |= 127;
        frame.push_back(second_byte);
        for (int i = 7; i >= 0; --i) {
            frame.push_back((payload_length_ >> (8 * i)) & 0xFF);
        }
    }
    
    // Masking key (服务器发送时不使用mask)
    if (masked_) {
        frame.insert(frame.end(), masking_key_.begin(), masking_key_.end());
    }
    
    // Payload data
    frame.insert(frame.end(), payload_.begin(), payload_.end());
    
    return frame;
}

bool WebSocketFrame::parse(const std::vector<uint8_t>& data) {
    if (data.size() < 2) return false;
    
    size_t index = 0;
    
    // 解析第一个字节
    fin_ = (data[index] & 0x80) != 0;
    rsv1_ = (data[index] & 0x40) != 0;
    rsv2_ = (data[index] & 0x20) != 0;
    rsv3_ = (data[index] & 0x10) != 0;
    opcode_ = static_cast<Opcode>(data[index] & 0x0F);
    index++;
    
    // 解析第二个字节
    masked_ = (data[index] & 0x80) != 0;
    uint64_t length = data[index] & 0x7F;
    index++;
    
    // 解析扩展长度
    if (length == 126) {
        if (data.size() < index + 2) return false;
        length = (data[index] << 8) | data[index + 1];
        index += 2;
    } else if (length == 127) {
        if (data.size() < index + 8) return false;
        length = 0;
        for (int i = 0; i < 8; ++i) {
            length = (length << 8) | data[index + i];
        }
        index += 8;
    }
    
    // 解析Masking key
    if (masked_) {
        if (data.size() < index + 4) return false;
        masking_key_.assign(data.begin() + index, data.begin() + index + 4);
        index += 4;
    }
    
    // 解析Payload
    if (data.size() < index + length) return false;
    payload_.assign(data.begin() + index, data.begin() + index + length);
    
    // 如果使用了mask，需要解码payload
    if (masked_) {
        for (size_t i = 0; i < payload_.size(); ++i) {
            payload_[i] ^= masking_key_[i % 4];
        }
    }
    
    payload_length_ = length;
    return true;
}

std::string WebSocketFrame::getPayloadAsString() const {
    return std::string(payload_.begin(), payload_.end());
}

WebSocketFrame WebSocketFrame::createTextFrame(const std::string& text) {
    std::vector<uint8_t> payload(text.begin(), text.end());
    return WebSocketFrame(Opcode::TEXT, payload);
}

WebSocketFrame WebSocketFrame::createCloseFrame(uint16_t code, const std::string& reason) {
    std::vector<uint8_t> payload;
    payload.push_back((code >> 8) & 0xFF);
    payload.push_back(code & 0xFF);
    payload.insert(payload.end(), reason.begin(), reason.end());
    return WebSocketFrame(Opcode::CLOSE, payload);
}

WebSocketFrame WebSocketFrame::createPingFrame(const std::vector<uint8_t>& data) {
    return WebSocketFrame(Opcode::PING, data);
}

WebSocketFrame WebSocketFrame::createPongFrame(const std::vector<uint8_t>& data) {
    return WebSocketFrame(Opcode::PONG, data);
}

} // namespace websocket